﻿#region

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

#endregion

namespace Tank90
{
    public class CustomMapPanel : Panel
    {
        public delegate void ClickDlg(Point point);

        private readonly List<Map> _maps = new List<Map>();
        private readonly Timer timer = new Timer();
        private bool Griding;
        private bool _isShowGrid;
        private MapElemenType _mapElemenType;

        public ClickDlg clickDlg;
        private Graphics drawGraphics;

        private Pen pen;
        private PictureBoxEx pictureBoxEx;

        public CustomMapPanel()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.DoubleBuffer, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
        }

        public MapElemenType mapElemenType
        {
            set { _mapElemenType = value; }
        }

        public bool IsShowGrid
        {
            get { return _isShowGrid; }
            set
            {
                _isShowGrid = value;
                //DrawGrid(value);
            }
        }

        public List<Map> maps
        {
            get { return _maps; }
        }

        private void InitializeComponent()
        {
            SuspendLayout();
            ResumeLayout(false);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            pictureBoxEx.SetProPrity(_mapElemenType, e.Location);
            pictureBoxEx.Visible = true;

            //this.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            drawGraphics = e.Graphics;
            DrawGrid(_isShowGrid, e.Graphics);
            DrawingMap();
            if (IsGetLocation(pictureBoxEx.Location.X))
            {
                DrawVcLine(GetInt(pictureBoxEx.Location.X));
            }
            if (IsGetLocation(pictureBoxEx.Location.Y))
            {
                DrawHzLine(GetInt(pictureBoxEx.Location.Y));
            }
        }

        protected override void OnCreateControl()
        {
            BackColor = Color.Black;
            for (int i = 0; i < 640; i += 20)
            {
                for (int j = 0; j < 640; j += 20)
                {
                    var map = new Map();
                    map.x = i;
                    map.y = j;
                    _maps.Add(map);
                }
            }

            clickDlg += _MouseClick; //委托的使用
            timer.Interval = 30;
            timer.Tick += timer_Tick;
            timer.Start();

            pictureBoxEx = new PictureBoxEx(clickDlg);
            pictureBoxEx.Visible = false;
            Controls.Add(pictureBoxEx);
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            Invalidate();
        }


        private void _MouseClick(Point point)
        {
            List<Map> map = GetMap(point);
            List<Map> tmpMaps = GetMapValueByType(map);
            if (map.Count == 4)
            {
                foreach (Map oMap in map)
                {
                    _maps.Remove(oMap);
                }
                foreach (Map tmpMap in tmpMaps)
                {
                    _maps.Add(tmpMap);
                }
                //   DrawingMap();
            }
        }

        private List<Map> GetMap(Point point)
        {
            return
                _maps.Where(
                    r =>
                        r.x <= (GetInt(point.X) + 20) && r.x > (GetInt(point.X) - 20) && r.y > (GetInt(point.Y) - 20) &&
                        r.y <= (GetInt(point.Y) + 20)).ToList();
        }

        private List<Map> GetMapValueByType(List<Map> maps)
        {
            switch (_mapElemenType)
            {
                    #region Stone

                case MapElemenType.FStone:
                    maps[0].elemenType = MapElemenType.OStone;
                    maps[1].elemenType = MapElemenType.OStone;
                    maps[2].elemenType = MapElemenType.OStone;
                    maps[3].elemenType = MapElemenType.OStone;
                    break;
                case MapElemenType.UStone:
                    maps[0].elemenType = MapElemenType.OStone;
                    maps[1].elemenType = MapElemenType.None;
                    maps[2].elemenType = MapElemenType.OStone;
                    maps[3].elemenType = MapElemenType.None;
                    break;
                case MapElemenType.DStone:
                    maps[0].elemenType = MapElemenType.None;
                    maps[1].elemenType = MapElemenType.OStone;
                    maps[2].elemenType = MapElemenType.None;
                    maps[3].elemenType = MapElemenType.OStone;
                    break;
                case MapElemenType.LStone:
                    maps[0].elemenType = MapElemenType.OStone;
                    maps[1].elemenType = MapElemenType.OStone;
                    maps[2].elemenType = MapElemenType.None;
                    maps[3].elemenType = MapElemenType.None;
                    break;
                case MapElemenType.RStone:
                    maps[0].elemenType = MapElemenType.None;
                    maps[1].elemenType = MapElemenType.None;
                    maps[2].elemenType = MapElemenType.OStone;
                    maps[3].elemenType = MapElemenType.OStone;
                    break;

                    #endregion

                    #region Brick

                case MapElemenType.FBrick:
                    maps[0].elemenType = MapElemenType.OBrick;
                    maps[1].elemenType = MapElemenType.OBrick;
                    maps[2].elemenType = MapElemenType.OBrick;
                    maps[3].elemenType = MapElemenType.OBrick;
                    break;
                case MapElemenType.UBrick:
                    maps[0].elemenType = MapElemenType.OBrick;
                    maps[1].elemenType = MapElemenType.None;
                    maps[2].elemenType = MapElemenType.OBrick;
                    maps[3].elemenType = MapElemenType.None;
                    break;
                case MapElemenType.DBrick:
                    maps[0].elemenType = MapElemenType.None;
                    maps[1].elemenType = MapElemenType.OBrick;
                    maps[2].elemenType = MapElemenType.None;
                    maps[3].elemenType = MapElemenType.OBrick;
                    break;
                case MapElemenType.LBrick:
                    maps[0].elemenType = MapElemenType.OBrick;
                    maps[1].elemenType = MapElemenType.OBrick;
                    maps[2].elemenType = MapElemenType.None;
                    maps[3].elemenType = MapElemenType.None;
                    break;
                case MapElemenType.RBrick:
                    maps[0].elemenType = MapElemenType.None;
                    maps[1].elemenType = MapElemenType.None;
                    maps[2].elemenType = MapElemenType.OBrick;
                    maps[3].elemenType = MapElemenType.OBrick;
                    break;

                    #endregion

                    #region Water

                case MapElemenType.Water:
                    maps[0].elemenType = MapElemenType.Water;
                    maps[1].elemenType = MapElemenType.Water;
                    maps[2].elemenType = MapElemenType.Water;
                    maps[3].elemenType = MapElemenType.Water;
                    break;
                case MapElemenType.Grass:
                    maps[0].elemenType = MapElemenType.Grass;
                    maps[1].elemenType = MapElemenType.Grass;
                    maps[2].elemenType = MapElemenType.Grass;
                    maps[3].elemenType = MapElemenType.Grass;
                    break;
                case MapElemenType.White:
                    maps[0].elemenType = MapElemenType.White;
                    maps[1].elemenType = MapElemenType.White;
                    maps[2].elemenType = MapElemenType.White;
                    maps[3].elemenType = MapElemenType.White;
                    break;
                default:
                    maps[0].elemenType = MapElemenType.None;
                    maps[1].elemenType = MapElemenType.None;
                    maps[2].elemenType = MapElemenType.None;
                    maps[3].elemenType = MapElemenType.None;
                    break;

                    #endregion
            }
            return maps;
        }

        private bool IsGetLocation(int lInt)
        {
            return
                ((lInt + 10)%40 == 0) ||
                ((lInt + 9)%40 == 0) ||
                ((lInt + 8)%40 == 0) ||
                ((lInt + 7)%40 == 0) ||
                ((lInt + 6)%40 == 0) ||
                ((lInt + 5)%40 == 0) ||
                (lInt + 4)%40 == 0 ||
                (lInt + 3)%40 == 0 ||
                (lInt + 1)%40 == 0 ||
                (lInt%40) == 0 ||
                ((lInt - 1)%40 == 0) ||
                (lInt - 2)%40 == 0 ||
                (lInt - 3)%40 == 0 ||
                (lInt - 4)%40 == 0 ||
                (lInt - 5)%40 == 0 ||
                ((lInt - 6)%40) == 0 ||
                (lInt - 7)%40 == 0 ||
                (lInt - 8)%40 == 0 ||
                (lInt - 9)%40 == 0 ||
                (lInt - 10)%40 == 0;

            ;
        }

        private int GetInt(int lInt)
        {
            return ((lInt + 11)/40)*40;
        }

        private void DrawVcLine(int xLine)
        {
            Brush brush = new SolidBrush(Color.Red);
            pen = new Pen(brush);
            //Graphics graphics = this.CreateGraphics();
            drawGraphics.DrawLine(pen, new Point(xLine, -100), new Point(xLine, 1000));
            pen.Dispose();
            //graphics.Dispose();
        }

        private void DrawHzLine(int yLine)
        {
            Brush brush = new SolidBrush(Color.Red);
            pen = new Pen(brush);
            //Graphics graphics = this.CreateGraphics();

            drawGraphics.DrawLine(pen, new Point(-100, yLine), new Point(1000, yLine));
            pen.Dispose();
            //graphics.Dispose();
        }

        private void DrawGrid(bool isShowGrid, Graphics graphics)
        {
            if (isShowGrid)
            {
                Brush brush = new SolidBrush(Color.White);
                pen = new Pen(brush);
                for (int i = 0; i <= 640; i += 40)
                {
                    for (int j = 0; j <= 640; j += 40)
                    {
                        graphics.DrawLine(pen, new Point(i, j), new Point(640 - i, j));
                        graphics.DrawLine(pen, new Point(j, i), new Point(j, 640 - i));
                    }
                }
                pen.Dispose();
                brush.Dispose();
                Griding = true;
            }
            else if (Griding)
            {
                Invalidate();
                Griding = false;
            }
        }

        private void DrawingMap()
        {
            if (drawGraphics != null)
            {
                foreach (Map map in _maps)
                {
                    map.Drawing(drawGraphics);
                }
            }
        }
    }
}